#include "tm_tmd1_export_target.h"
#include "tm_tmd_utils.h"

//legacy TMD 1 file format
//file format of the ST-FreePascal engine
//TEngine should be backwards compatible with this

//limitations:
//-only exports basic mesh (vert, normal, uv)
//-the tbn matrix storage is unused and wastes space
//-the file is pre-interleaved which uses more disk space but reduces game load time

MStatus TTMD1ExportTarget::GetOutputPath(MString& target)
{
	MStringArray ResultArray;
	
	MStatus stat = MGlobal::executeCommand("fileDialog2 -fm 0 -ds 2 -dir \".\" -ff \"TMD (*.tmd)\"", ResultArray, true, false);

	target = ResultArray[0];

	return stat;
}

MStatus TTMD1ExportTarget::SaveFile(MString filename)
{
	MStatus stat;

	Compile();

	TMDHeader FileHeader;
	FileHeader.IndexCount = Data.index_count;
	FileHeader.VertexCount = Data.vertex_count;
	FileHeader.Frames = 0;

	FILE* tmdfile;

	fopen_s(&tmdfile, filename.asChar(), "wb");
	if (!tmdfile)
	{
		stat.perror("Could not open file for writing.");
		return stat;
	}

	fwrite(&FileHeader, sizeof(FileHeader), 1, tmdfile);

	fwrite(Data.vertices, sizeof(Vertex), Data.vertex_count, tmdfile);
	fwrite(Data.indices, sizeof(unsigned int), Data.index_count, tmdfile);

	fclose(tmdfile);

	cout << "Saved TMD file to " << filename.asChar() << endl;

	stat = MS::kSuccess;	
	return stat;
}

void TTMD1ExportTarget::Compile()
{
	cout << "Compiling vertices in " << Meshes.size() << " meshes..." << endl;
	
	std::vector<Vertex> FinalVerts;
	
	unsigned int index_offset = 0;
	
	for (int meshno=0; meshno!= Meshes.size(); ++meshno)
	{
		cout << " *Mesh #" << meshno << ": " <<Meshes[meshno].Triangles.size() << " triangles." << endl;
		
		for (int trino=0; trino!=Meshes[meshno].Triangles.size(); ++trino)
		{
			for (int trivert=0; trivert < 3; ++trivert)
			{
				Vertex thisvert;

				int vertidx = Meshes[meshno].Triangles[trino].vertex_idx[trivert];
				int normidx = Meshes[meshno].Triangles[trino].normal_idx[trivert];
				int uvidx = Meshes[meshno].Triangles[trino].uv_idx[trivert];

				thisvert.Position[0] = (float)Meshes[meshno].Vertices[vertidx].x;
				thisvert.Position[1] = (float)Meshes[meshno].Vertices[vertidx].y;
				thisvert.Position[2] = (float)Meshes[meshno].Vertices[vertidx].z;

				thisvert.Normal[0] = Meshes[meshno].Normals[normidx].x;
				thisvert.Normal[1] = Meshes[meshno].Normals[normidx].y;
				thisvert.Normal[2] = Meshes[meshno].Normals[normidx].z;

				thisvert.TexCoord[0] = Meshes[meshno].U_Coords[uvidx];
				thisvert.TexCoord[1] = Meshes[meshno].V_Coords[uvidx];

				FinalVerts.push_back(thisvert);
			}
		}
	}
	
	std::vector<Vertex> FilteredFinalVerts;
	std::vector<Index> FinalIndices;
	
	for (int i=0; i<FinalVerts.size(); ++i)
		FinalIndices.push_back(AddDropDuplicates(FinalVerts[i], FilteredFinalVerts));

	Data.index_count = (long)FinalIndices.size();
	Data.vertex_count = (long)FilteredFinalVerts.size();

	Data.vertices = new Vertex[Data.vertex_count];
	Data.indices = new unsigned int[Data.index_count];
	
	for (int i=0; i<Data.vertex_count; ++i)
		Data.vertices[i] = FilteredFinalVerts[i];

	for (int i=0; i<Data.index_count; ++i)
		Data.indices[i] = FinalIndices[i];
}

void TTMD1ExportTarget::AddMesh(TMayaExportMesh& mesh)
{
	Meshes.push_back(mesh);
}